home *** CD-ROM | disk | FTP | other *** search
- /*
- * Copyright (C) 1985-1992 New York University
- *
- * This file is part of the Ada/Ed-C system. See the Ada/Ed README file for
- * warranty (none) and distribution info and also the GNU General Public
- * License for more details.
-
- */
-
- /* load.c - procedures to load to libraries and axq files */
-
- #include <stdlib.h>
- #include <stdio.h>
- #include <string.h>
- #include "config.h"
- #include "int.h"
- #include "segment.h"
- #include "slot.h"
- #include "ivars.h"
- #include "ifile.h"
- #ifdef vms
- /*
- #include "adaexec.h"
- #include descrip
- */
- #endif
- #include "miscprots.h"
- #include "libfprots.h"
- #include "axqrprots.h"
- #include "loadprots.h"
-
- static void init_predef();
- static void init_library(IFILE *, char *);
- static char *unit_name_name(char *);
- static int *unit_list_new();
- static void unit_list_copy(int *, int *);
- static int unit_list_next(int *);
- static int in_loaded(char *);
-
- /* Various sets and maps in the SETL version are represented using
- * strings in the C version. This is possible since they all have as
- * their domain unit_numbers, and the total number of unit_numbers is
- * known before these are needed. The initial values of these items
- * are set by
- * s = unit_list_new().
- * Once defined, s[i] is YES if unit i is in the set, NO otherwise.
- * These sets are kept as a vector of (short) integers, with the
- * first (zeroth) element giving the number of elements, in much the
- * way is tuples are represented in the other parts of the compiler.
- */
- #define YES 1
- #define NO 0
-
- static char **file_number;
- static int **PRECEDES_MAP;
- static char **unit_names;
- static int unit_count;
- static int interfaced_unit = 0;
- static int obsolete_error = FALSE;
-
- /* The following struct is used main a list of the units actually loaded. */
- struct axq_loaded {
- struct axq_loaded *loaded_next;
- char *loaded_name;
- };
- static struct axq_loaded *ll_head; /* pointer to head of list */
-
- static void init_predef() /*;init_predef*/
- {
- int i;
- static char *predef_units[] = {
- "spSYSTEM", "spIO_EXCEPTIONS", "spSEQUENTIAL_IO",
- "boSEQUENTIAL_IO", "spDIRECT_IO", "boDIRECT_IO",
- "spTEXT_IO", "boTEXT_IO", "spCALENDAR", "boCALENDAR",
- "ssUNCHECKED_DEALLOCATION", "suUNCHECKED_DEALLOCATION",
- "ssUNCHECKED_CONVERSION", "suUNCHECKED_CONVERSION"
- #ifdef PREDEF_PC
- ,"spTEXT_IO_TYPES", "spTIO_MANAGE", "boTIO_MANAGE",
- "spTIO_DEFAULT", "boTIO_DEFAULT", "spTIO_LENGTH",
- "boTIO_LENGTH", "spTIO_LAYOUT", "boTIO_LAYOUT",
- "spTIO_STRING", "boTIO_STRING",
- "spTIO_INTEGER", "boTIO_INTEGER",
- "spTIO_FLOAT", "boTIO_FLOAT",
- "spTIO_FIXED", "boTIO_FIXED",
- "spTIO_ENUMERATION", "boTIO_ENUMERATION",
- "spINTEGER_TEXT_IO", "boINTEGER_TEXT_IO",
- "spFLOAT_TEXT_IO", "boFLOAT_TEXT_IO"
- #endif
- };
-
- /* Set values for unit_names, file_number and PRECEDES information for
- * predefined compilation units, since they do not appear in any library
- */
- /* allocate unit names - recalling it is ones origin */
- #ifdef PREDEF_PC
- unit_count = 37;
- #else
- unit_count = 14;
- #endif
- unit_names = (char **) emalloct((unit_count + 1) * sizeof(char *),
- "unit_names");
- PRECEDES_MAP = (int **) emalloct(sizeof(char **) *(unit_count + 1),
- "precedes_map");
- PRECEDES_MAP[0] = (int *) unit_count;
- file_number = (char **) emalloct(sizeof(char **) *(unit_count + 1),
- "file_number");
- for (i = 1; i <= unit_count; i++) {
- unit_names[i] = predef_units[i - 1];
- file_number[i] = "0";
- PRECEDES_MAP[i] = unit_list_new();
- }
- }
-
- void load_lib(char *filename, IFILE *libfile, Axq axq, char *main_unit,
- char **argv) /*;load_lib*/
- {
- /* This procedure looks for the main unit
- * and loads it, together with all units on which it depends directly
- * or indirectly. Dependences are taken from map precedes.
- */
-
- struct axq_loaded *ll_new;
- int *main_units, *bound_units, *new_main_units, *to_read, *precedes;
- int unitn;
- int i, name, pi;
- int is_predef_unit;
- int nmain_units;
- char *idle_task_name, *unit_file;
- IFILE * axqfile;
- char exename[100];
- char *PREDEFNAME;
- char *file_name, *l_name, *t_name;
- #ifdef vms
- struct dsc$descriptor_s string_desc;
- #endif
-
- ll_head = (struct axq_loaded *) 0; /* Initially, no files loaded */
- init_library(libfile,main_unit);
- main_units = unit_list_new();
- bound_units = unit_list_new();
- for (i = 1; i <= unit_count; i++) {
- if (streq(unit_name_type(unit_names[i]), "ma"))
- main_units[i] = YES;
- }
- if (main_unit != (char *) 0) {
- /* main_units := {[x,y]: [x,y] in main_units
- * | y = '_'+MAINUNIT+'_idle_task'};
- */
- idle_task_name = strjoin(main_unit, "_idle_task");
- for (name = 1; name <= unit_count; name++) {
- if (main_units[name] == NO)
- continue;
- if (streq(idle_task_name, unit_names[name]+2))
- bound_units[name] = YES;
- }
- unit_list_copy(main_units, bound_units);
- }
- nmain_units = 0;
- for (i = 1; i <= main_units[0]; i++)
- if (main_units[i]) nmain_units++;
- if (nmain_units == 0) {
- #ifdef vms
- LIB$SIGNAL(MSG_NOTBOUND);
- exit();
- #else
- printf("*** Unbound library, execution not allowed\n");
- exit(RC_ERRORS);
- #endif
- }
- else if (nmain_units > 1) {
- #ifdef vms
- LIB$SIGNAL(MSG_MANYMAIN);
- LIB$SIGNAL(MSG_SPECIFY);
- for (name = 1; name <= unit_count; name++) {
- if (main_units[name] == NO)
- continue;
- /* name of the form _xxx_idle_task, print only xxx */
- unit_names[name][strlen(unit_names[name])-10] = '\0';
- string_desc.dsc$w_length = strlen(unit_names[name]+2);
- string_desc.dsc$b_dtype = DSC$K_DTYPE_T;
- string_desc.dsc$b_class = DSC$K_CLASS_S;
- string_desc.dsc$a_pointer = unit_names[name]+2;
- LIB$SIGNAL(MSG_MAIN,1,&string_desc);
- }
- exit();
- #else
- printf("*** More than one main program in library\n");
- printf(" Use option: -m(one of the following)\n");
- for (name = 1; name <= unit_count; name++) {
- if (main_units[name] == NO)
- continue;
- unit_names[name][strlen(unit_names[name])-10] = '\0';
- /* name of the form _xxx_idle_task, print only xxx */
- printf(" %s\n", unit_names[name]+2);
- }
- exit(RC_ERRORS);
- #endif
- }
- else {
- #ifndef INTERFACE
- #ifdef SUPPORT_PRAGMA_INTERFACE
- /* at this point, if the main binding unit is interfaced, we run
- * the executable which has been built with the procedure interface
- */
- if (interfaced_unit != 0) {
- sprintf(exename,"%s%s%s.exe",filename,DIR_DELIMITER,
- file_number[interfaced_unit]);
- execvp(exename,argv);
- }
- #endif
- #endif
- if (obsolete_error) {
- printf(
- "*** Main binding unit obsolete, please recompile or rebind \n");
- exit(RC_ERRORS);
- }
- to_read = unit_list_new();
- while(unit_list_next(main_units)) {
- for (name = 1; name <= unit_count; name++) {
- if (main_units[name] == NO)
- continue;
- to_read[name] = YES;
- }
- /* main_units := {} +/{ precedes{u} : u in main_units}; */
- new_main_units = unit_list_new();
- /* for name in main_units */
- for (name = 1; name <= unit_count; name++) {
- if (main_units[name] == NO)
- continue;
- precedes = PRECEDES_MAP[name];
- for (pi = 1; pi <= unit_count; pi++) {
- if (precedes[pi] == NO)
- continue;
- new_main_units[pi] = YES;
- }
- }
- unit_list_copy(main_units, new_main_units);
- }
- while((unitn = unit_list_next(to_read))) {
- to_read[unitn] = NO; /* remove from set */
- if (unitn == 0) {
- /* junk unit number - binder shouldn't be putting this out */
- printf("load.c: skipping 0 case\n");
- continue;
- }
- if (unitn <= unit_count /* false if "ghost package body" */
- &&(!in_loaded(file_number[unitn]))) {
- unit_file = (char *) file_number[unitn];
- file_name = unit_file;
- is_predef_unit = streq(unit_file,"0");
- if (is_predef_unit) {
- PREDEFNAME = predef_env();
- l_name = libset(PREDEFNAME); /* use predef library */
- file_name = "predef";
- }
- axqfile = ifopen(file_name, "axq", "r", "a", iot_ais_r, 0);
- read_axq(axqfile, axq);
- ifclose(axqfile);
- if (is_predef_unit)
- t_name = libset(l_name); /* restore user library */
- if (!in_loaded(unit_file))
- ll_new = (struct axq_loaded *)
- smalloc(sizeof(struct axq_loaded));
- ll_new->loaded_next = ll_head;
- ll_new->loaded_name = unit_file;
- ll_head = ll_new;
- }
- } /* while */
- }
- }
-
- static void init_library(IFILE *ifile, char *main_unit) /*;init_library*/
- {
- /*
- * retrieve information from ifile
- */
-
- int i, j, n, m, unumber,cur_level;
- int ignore;
- int punit;
- char *uname, *aisname;
- int *precedes;
- char *main_binding_unit = (char *)0;
- int units_lib;
- int is_interfaced,comp_status;
-
- init_predef();
- ll_head = (struct axq_loaded *) 0;
- if (ifile == (IFILE *) 0) {
- #ifdef vms
- LIB$SIGNAL(MSG_LIBRARY);
- exit();
- #else
- printf("*** library is empty\n");
- exit(RC_ERRORS);
- #endif
- }
- units_lib = getnum(ifile, "lib-unit-count");
- unit_count = getnum(ifile, "lib-unit_num");
- getnum(ifile, "lib-empty-slots"); /* ignore */
- getstr(ifile, "lib-tmp-str"); /* ignore */
- unit_names = (char **) erealloct((char *)unit_names,
- (unit_count+1) * sizeof(char **), "unit_names-re");
-
- file_number = (char **) erealloct((char *)file_number,
- sizeof(char **) *(unit_count+1),"file_number-re");
- #ifndef INTERFACE
- if (main_unit != (char *)0) {
- /* a main unit was specified */
- main_binding_unit = strjoin("ma",main_unit);
- main_binding_unit = strjoin(main_binding_unit,"_idle_task");
- }
- #endif
- for (i = 1; i <= units_lib; i++) {
- uname = getstr(ifile, "lib-unit-name");
- unumber = getnum(ifile, "lib-unit-number");
- aisname = getstr(ifile, "lib-ais-name");
- getstr(ifile, "comp-date"); /* ignore */
- getnum(ifile, "lib-symbols"); /* ignore */
- getnum(ifile, "lib-nodes"); /* ignore */
- is_interfaced = getnum(ifile, "lib-is-main");
- #ifdef SUPPORT_PRAGMA_INTERFACE
- #ifndef INTERFACE
- if (main_binding_unit != (char *) 0) {
- /* check is_main (interfaced flag) only for binding unit
- * corresponding to specified main unit
- */
- if (streq(uname,main_binding_unit) && is_interfaced)
- interfaced_unit = unumber;
- }
- else {
- /* look at is_main (interfaced flag) for any main binding unit.
- * if there is more that one of these, we will report an error
- * later !!
- */
- if (streq(unit_name_type(uname),"ma") && is_interfaced)
- interfaced_unit = unumber;
- }
- #endif
- #endif
- comp_status = getnum(ifile, "lib-status");
- /* verify that main binding unit status is not obsolete */
- /* ignore this field for all other units */
- if (main_binding_unit != (char *) 0) {
- /* check comp_status only for specified main binding unit */
- if (streq(uname,main_binding_unit) && !comp_status)
- obsolete_error = TRUE;
- }
- else {
- /* if none specified, check for any main binding unit */
- if (streq(unit_name_type(uname),"ma") && !comp_status)
- obsolete_error = TRUE;
- }
- unit_names[unumber] = strjoin(uname, "");
- file_number[unumber] = strjoin(aisname, "");
- }
- /* read but ignore stub info */
- n = getnum(ifile, "lib-n");
- for (i = 1; i <= n; i++) {
- uname = getstr(ifile, "lib-unit-name");
- aisname = getstr(ifile, "lib-ais-name");
- ignore = getnum(ifile, "lib-parent");
- cur_level = getnum(ifile, "lib-cur_level");
- m = getnum(ifile, "stub-file-size");
- for (j = 1; j <= m; j++)
- ignore = getnum(ifile, "stub-file");
- }
-
- PRECEDES_MAP = (int **) emalloct(sizeof(char **) *(unit_count + 1),
- "precedes_map");
- for (i = 1; i <= unit_count; i++)
- PRECEDES_MAP[i] = unit_list_new();
- n = getnum(ifile, "precedes-map-size");
- for (i = 1; i <= n; i += 2) {
- unumber = getnum(ifile, "precedes-map-ent");
- m = getnum(ifile, "precedes-map-set-size");
- precedes = unit_list_new();
- for (j = 1; j <= m; j++) {
- punit = getnum(ifile, "precedes-map-ent");
- precedes[punit] = YES;
- }
- if (unumber==0) chaos("unit number zero");
- PRECEDES_MAP[unumber] = precedes;
- }
- return;
- }
-
- static char *unit_name_name(char *u) /*;unit_name_name*/
- {
- int n;
- char *s1, *s2;
-
- n = strlen(u);
- if (n <= 2)
- return (char *) 0;
-
- s1 = u + 2; /* point to start of name */
- s2 = strchr(s1, '.'); /* look for dot after first name */
- if (s2 == (char *) 0) /* if no dot take rest of string */
- s2 = u + n; /* find end */
- n = s2 - s1;
- s2 = smalloc((unsigned) n + 1);
- strncpy(s2, s1, n);
- s2[n] = '\0'; /* terminate result */
- return (s2);
- }
-
- long load_slots(char *fname, IFILE **ifile, Axq axq) /*;load_slots*/
- {
- IFILE *AXQFILE;
- Slot slot;
- int i;
- long cde_pos;
-
- AXQFILE = ifopen(LIBFILENAME, "", "r", "l", iot_lib_r, 0);
- cde_pos = get_cde_slots(AXQFILE, axq);
- *ifile = AXQFILE; /* store file pointer */
-
- code_slots_dim = axq->axq_code_segments_dim;
- data_slots_dim = axq->axq_data_segments_dim;
- exception_slots_dim = axq->axq_exception_slots_dim;
- code_slots = (char **) ecalloct(code_slots_dim, sizeof(char *),
- "code_slots");
- data_slots = (char **) ecalloct(data_slots_dim, sizeof(char *),
- "data_slots");
- exception_slots = (char **) ecalloct(exception_slots_dim, sizeof(char *),
- "exception_slots");
- /* now get names from list and put in proper place */
- for (i = 1; i < axq->axq_code_slots_dim; i++) {
- slot = axq->axq_code_slots[i];
- if (slot == (Slot) 0)
- continue;
- if (slot->slot_number == 0)
- continue;
- code_slots[slot->slot_number] = slot->slot_name;
- }
- for (i = 1; i < axq->axq_data_slots_dim; i++) {
- slot = axq->axq_data_slots[i];
- if (slot == (Slot) 0)
- continue;
- if (slot->slot_number == 0)
- continue;
- data_slots[slot->slot_number] = slot->slot_name;
- }
- for (i = 1; i < axq->axq_exception_slots_dim; i++) {
- slot = axq->axq_exception_slots[i];
- if (slot == (Slot) 0)
- continue;
- if (slot->slot_number == 0)
- continue;
- exception_slots[slot->slot_number] = slot->slot_name;
- }
- code_segments_dim = axq->axq_code_segments_dim;
- code_segments = (char **) ecalloct(axq->axq_code_segments_dim,
- sizeof(char *),"code_segments");
- code_seglen = (int *) ecalloct(axq->axq_code_segments_dim, sizeof(int),
- "code_seglen");
- axq->axq_code_segments = code_segments;
- axq->axq_code_seglen = code_seglen;
- data_segments_dim = axq->axq_data_segments_dim;
- data_segments = (int **) ecalloct(axq->axq_data_segments_dim,
- sizeof(char *),"data_segments");
- data_seglen = (int *) ecalloct(axq->axq_data_segments_dim, sizeof(int),
- "data_seglen");
- axq->axq_data_segments = data_segments;
- axq->axq_data_seglen = data_seglen;
-
- if ((*ifile)->fh_trace) {
- for (i = 1; i < axq->axq_code_segments_dim; i++)
- printf("code_segment %2d length %8d\n",i,code_seglen[i]);
- for (i = 1; i < axq->axq_data_segments_dim; i++)
- printf("data_segment %2d length %8d\n",i,data_seglen[i]);
- }
- return cde_pos;
- }
-
- static int *unit_list_new() /*;unit_list_new*/
- {
- int *u;
-
- u = (int *) smalloc(sizeof(int) * (unit_count + 1));
- u[0] = unit_count;
- for (i = 1; i <= unit_count; i++)
- u[i] = NO;
- return u;
- }
-
- static void unit_list_copy(int *u1, int *u2) /*;unit_list_copy*/
- {
- int n,i;
-
- n = u1[0];
- if (n != u2[0])
- chaos("unit_copy sizes differ");
- for (i = 1; i <= n; i++)
- u1[i] = u2[i];
- }
-
- static int unit_list_next(int *u1) /*;unit_list_next*/
- {
- int i,n;
-
- n = u1[0];
- for (i = 1; i <= n; i++)
- if (u1[i]) return i;
- return 0;
- }
-
- static int in_loaded(char *str) /*;in_loaded*/
- {
- /* test to see if named file has been loaded */
- struct axq_loaded *p;
-
- for (p = ll_head; p != (struct axq_loaded *) 0; p = p->loaded_next)
- if (streq(str, p->loaded_name))
- return TRUE;
-
- return FALSE;
- }
-